'''
注意：使用hugging face相关功能可能需要科学上网
如果网络连接不行，可以手动下载模型后再运行此代码
'''

# 导入必要的库
from langchain_huggingface import HuggingFaceEmbeddings  # LangChain对HuggingFace嵌入模型的封装
from sentence_transformers import SentenceTransformer  # 句子转换器库，用于文本嵌入

# 下载并保存基础模型
model_name = "all-MiniLM-L6-v2"  # 选择使用的预训练模型名称
# 这是一个轻量级的句子嵌入模型，平衡了性能与效率
# 特点：6层网络，384维嵌入向量，在多语言任务上表现良好

# 初始化句子转换器模型
model = SentenceTransformer(model_name)
# 这行代码会：
# 1. 检查本地是否已有该模型
# 2. 如果没有，则从huggingface仓库下载
# 3. 加载模型到内存中

# 创建HuggingFaceEmbeddings封装器
# 相比直接使用SentenceTransformer，这个封装器提供了更高级的接口
# 特别适合与LangChain框架集成使用
embeddings = HuggingFaceEmbeddings(
    # 指定模型路径或名称
    # 方式1：使用在线模型名称（需要网络）
    # model_name="sentence-transformers/all-MiniLM-L6-v2",

    # 方式2：使用本地已下载的模型路径（推荐，避免重复下载）
    model_name="D:\models\sentence-transformersall-MiniLM-L6-v2",

    # 模型配置参数
    model_kwargs={
        'device': 'cpu',  # 指定运行设备：'cpu'或'cuda'
        # 如果使用GPU可改为 'cuda:0' 或 'cuda'
    },

    # 编码参数
    encode_kwargs={
        'normalize_embeddings': True,  # 是否对嵌入向量进行归一化
        # 归一化的好处：
        # - 提高余弦相似度计算的准确性
        # - 使向量模长为1，便于相似度比较
        # - 通常能提升检索效果

        'batch_size': 32  # 批处理大小
        # 较大的batch_size可以提高处理效率
        # 但需要根据可用内存调整
    }
)

# 将模型保存到本地指定路径
# 这样以后就可以直接从本地加载，无需重复下载
model.save("path_to_save_model")
# 保存的内容包括：
# - 模型权重
# - 模型配置文件
# - 词汇表等必要文件

# 自定义保存路径示例（取消注释即可使用）
# model.save("d:/my_models/all-MiniLM-L6-v2")
# 建议使用有意义的路径名，便于后续管理

# 使用示例（可以添加以下代码来测试模型）：
# text = "这是一个测试句子"
# embedding_vector = embeddings.embed_query(text)
# print(f"嵌入向量维度: {len(embedding_vector)}")
# print(f"嵌入向量示例: {embedding_vector[:5]}")  # 显示前5个维度